using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using ClickNET.IO;

namespace ClickNET.Imaging
{
    public class Picture : ImageEntity
    {
        static readonly object padlock = new object();

        public Picture() { }

        public Picture(string pathToFile, string folderName) : base(pathToFile)
        {
            if (File.Exists(pathToFile))
            {
                this.Load();
                this.Title = this.FileName.Split('.')[0]; // remove extension from default title
                this.Description = string.Empty;
                this.FolderName = folderName;
                this.Url = FileSystemGalleryManager.GetImageUrl(this.FolderName, this.FileName);
            }
        }

        public bool Exists()
        {
            return File.Exists(this.Path);
        }

        public bool ThumbnailsExist()
        {
            string smallThumbLocation = FileSystemGalleryManager.GetThumbnailFilesystemPath(this.FolderName, this.FileName, SMALL_THUMB_SIZE);
            string largeThumbLocation = FileSystemGalleryManager.GetThumbnailFilesystemPath(this.FolderName, this.FileName, LARGE_THUMB_SIZE);

            return (File.Exists(smallThumbLocation) && File.Exists(largeThumbLocation));
        }

        public void EnsureThumbnailsExist()
        {
            if (!this.ThumbnailsExist())
                this.CreateThumbnails();
        }

        public void Save()
        {
            // Create thumbnails and save image to DB
        }

        public void CreateThumbnails()
        {
            try
            {
                lock (padlock)
                {
                    List<int> thumbSizes = new List<int>();

                    if (!String.IsNullOrEmpty(this.FileName))
                    {
                        thumbSizes.Add(SMALL_THUMB_SIZE);
                        thumbSizes.Add(LARGE_THUMB_SIZE);

                        // Has the file already been generated and inserted?
                        // If so - do nothing
                        if (!this.ThumbnailsExist() && Picture.FileNameHasAllowedExtension(this.FileName))
                        {
                            this.EnsureThumbsDirExists();

                            ImageResize imgResize = new ImageResize
                            {
                                File = this.Path,
                                UseLongestDimension = true
                            };

                            foreach (int thumbSize in thumbSizes)
                            {
                                string filePath = FileSystemGalleryManager.GetThumbnailFilesystemPath(this.FolderName, this.FileName, thumbSize);

                                imgResize.Size = thumbSize;
                                imgResize.GetThumbnail().Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Log.DefaultLog.WriteLine(String.Format("Error creating thumbnails for {0}\nException:\n" + e.ToString(), this.Path));
            }
        }

        public string GetThumbFileName(int size)
        {
            return String.Format(s_thumbsFilePrefixFormat, size, this.FileName);
        }

        private string GetThumbsDir()
        {
            return "/" + s_galleryDirectory + "/" + this.FolderName + "/" + s_thumbsDirectory;
        }

        private string GetImageStoreFilesystemDir()
        {
            return System.IO.Path.Combine(Config.DataDirectory, s_galleryDirectory);
        }

        private string GetSingleGalleryFilesystemDir()
        {
            return System.IO.Path.Combine(this.GetImageStoreFilesystemDir(), this.FolderName);
        }

        public string GetThumbsDirFilesystemPath()
        {
            string thumbsDir = System.IO.Path.Combine(Config.DataDirectory, s_thumbsDirectory);
            return System.IO.Path.Combine(thumbsDir, this.FolderName);
        }

        private void EnsureThumbsDirExists()
        {
            string thumbsDir = this.GetThumbsDirFilesystemPath();

            if (!Directory.Exists(thumbsDir))
                Directory.CreateDirectory(thumbsDir);
        }

        public static bool FileNameHasAllowedExtension(string fullPathToFile)
        {
            FileInfo fi = new FileInfo(fullPathToFile);

            foreach (string s in s_allowedFileExtensions)
            {
                if (fi.Extension.Equals(s, StringComparison.OrdinalIgnoreCase))
                    return true;
            }

            return false;
        }

        public string GetHumanReadableFileSize()
        {
            return ClickNET.Utility.StringConversion.GetHumanReadableFileSize(this.FileSize);
        }

        [XmlElement]
        public string Url { get; set; }

        [XmlElement]
        public string Title { get; set; }

        [XmlElement]
        public string Description { get; set; }

        [XmlElement]
        public string FolderName { get; set; } // TODO: Parse this out of base.Path every time and remove from serialization

        private const int SMALL_THUMB_SIZE = 100;
        private const int LARGE_THUMB_SIZE = 400;

        private static readonly string s_galleryDirectory = Config.DefaultInstance.GetConfigString("gallery", "imageDirectory");
        private static readonly string s_thumbsDirectory = Config.DefaultInstance.GetConfigString("gallery", "thumbsDirectory");
        private static readonly string s_thumbsFilePrefixFormat = Config.DefaultInstance.GetConfigString("gallery", "thumbsFilePrefixFormat");
        private static readonly List<string> s_allowedFileExtensions = Config.DefaultInstance.GetConfigCommaSeparatedString("gallery", "allowedFileExtensions", ".jpeg,.jpg,.png,.gif,.tiff,.tif");
    }
}
